package com.xiaoyu.util2;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateUtil {
	private static String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	private static String DATE_FORMAT = "yyyy-MM-dd";

	private static String TIME_FORMAT = "HH:mm:ss";

	private static ThreadLocal<SimpleDateFormat> ThreadDateTime = new ThreadLocal<SimpleDateFormat>();

	private static ThreadLocal<SimpleDateFormat> ThreadDate = new ThreadLocal<SimpleDateFormat>();

	private static ThreadLocal<SimpleDateFormat> ThreadTime = new ThreadLocal<SimpleDateFormat>();

	private static SimpleDateFormat DateTimeInstance() {
		SimpleDateFormat df = (SimpleDateFormat) ThreadDateTime.get();
		if (df == null) {
			df = new SimpleDateFormat(DATETIME_FORMAT);
			ThreadDateTime.set(df);
		}
		return df;
	}

	private static SimpleDateFormat DateInstance() {
		SimpleDateFormat df = (SimpleDateFormat) ThreadDate.get();
		if (df == null) {
			df = new SimpleDateFormat(DATE_FORMAT);
			ThreadDate.set(df);
		}
		return df;
	}

	private static SimpleDateFormat TimeInstance() {
		SimpleDateFormat df = (SimpleDateFormat) ThreadTime.get();
		if (df == null) {
			df = new SimpleDateFormat(TIME_FORMAT);
			ThreadTime.set(df);
		}
		return df;
	}

	public static String DateTime() {
		return DateTimeInstance().format(new Date());
	}

	public static String DateTime(Date date) {
		return DateTimeInstance().format(date);
	}

	public static Date DateTime(String datestr) throws ParseException {
		return DateTimeInstance().parse(datestr);
	}

	public static String Date() {
		return DateInstance().format(new Date());
	}

	public static String Date(Date date) {
		return DateInstance().format(date);
	}

	public static Date Date(String dateStr) throws ParseException {
		return DateInstance().parse(dateStr);
	}

	public static String Time() {
		return TimeInstance().format(new Date());
	}

	public static String Time(Date date) {
		return TimeInstance().format(date);
	}

	public static Date Time(String dateStr) throws ParseException {
		return TimeInstance().parse(dateStr);
	}

	public static Date year(int year) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(1, year);
		return Cal.getTime();
	}

	public static Date year(Date date, int year) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(date);
		Cal.add(1, year);
		return Cal.getTime();
	}

	public static Date month(int month) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(2, month);
		return Cal.getTime();
	}

	public static Date month(Date date, int month) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(date);
		Cal.add(2, month);
		return Cal.getTime();
	}

	public static Date day(int day) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(6, day);
		return Cal.getTime();
	}

	public static Date day(Date date, int day) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(date);
		Cal.add(6, day);
		return Cal.getTime();
	}

	public static Date hour(float hour) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(12, (int) (hour * 60.0F));
		return Cal.getTime();
	}

	public static Date hour(Date date, float hour) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(date);
		Cal.add(12, (int) (hour * 60.0F));
		return Cal.getTime();
	}

	public static Date Minute(int minute) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(12, minute);
		return Cal.getTime();
	}

	public static Date Minute(Date date, int minute) {
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(date);
		Cal.add(12, minute);
		return Cal.getTime();
	}

	public static boolean isDate(String date) {
		try {
			DateTimeInstance().parse(date);
			return true;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}

	public static long Subtract(Date date1, Date date2) {
		long cha = (date2.getTime() - date1.getTime()) / 1000L;
		return cha;
	}

	public static long Subtract(String date1, String date2) {
		long rs = 0L;
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long cha = (end.getTime() - start.getTime()) / 1000L;
			rs = cha;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public static int SubtractMinute(String date1, String date2) {
		int rs = 0;
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long cha = (end.getTime() - start.getTime()) / 1000L;
			rs = (int) cha / 60;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public static int SubtractMinute(Date date1, Date date2) {
		long cha = date2.getTime() - date1.getTime();
		return ((int) cha / 60000);
	}

	public static int SubtractHour(Date date1, Date date2) {
		long cha = (date2.getTime() - date1.getTime()) / 1000L;
		return ((int) cha / 3600);
	}

	public static int SubtractHour(String date1, String date2) {
		int rs = 0;
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long cha = (end.getTime() - start.getTime()) / 1000L;
			rs = (int) cha / 3600;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public static int SubtractDay(String date1, String date2) {
		int rs = 0;
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long sss = (end.getTime() - start.getTime()) / 1000L;
			rs = (int) sss / 86400;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public static int SubtractDay(Date date1, Date date2) {
		long cha = date2.getTime() - date1.getTime();
		return ((int) cha / 86400000);
	}

	public static int SubtractMonth(String date1, String date2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		int result;
		try {
			c1.setTime(DateInstance().parse(date1));
			c2.setTime(DateInstance().parse(date2));
			int year1 = c1.get(1);
			int month1 = c1.get(2);
			int year2 = c2.get(1);
			int month2 = c2.get(2);
			if (year1 == year2)
				result = month2 - month1;
			else
				result = 12 * (year2 - year1) + month2 - month1;
		} catch (ParseException e) {
			e.printStackTrace();
			result = -1;
		}
		return result;
	}

	public static int SubtractMonth(Date date1, Date date2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(date1);
		c2.setTime(date2);
		int year1 = c1.get(1);
		int month1 = c1.get(2);
		int year2 = c2.get(1);
		int month2 = c2.get(2);
		int result;
		if (year1 == year2)
			result = month2 - month1;
		else {
			result = 12 * (year2 - year1) + month2 - month1;
		}
		return result;
	}

	public static int SubtractYear(String date1, String date2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		int result;
		try {
			c1.setTime(DateInstance().parse(date1));
			c2.setTime(DateInstance().parse(date2));
			int year1 = c1.get(1);
			int year2 = c2.get(1);
			result = year2 - year1;
		} catch (ParseException e) {
			e.printStackTrace();
			result = -1;
		}
		return result;
	}

	public static int SubtractYear(Date date1, Date date2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(date1);
		c2.setTime(date2);
		int year1 = c1.get(1);
		int year2 = c2.get(1);
		int result = year2 - year1;
		return result;
	}

	public static String SubtractTime(String date1, String date2) {
		String result = "";
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long sss = (end.getTime() - start.getTime()) / 1000L;
			int hh = (int) sss / 3600;
			int mm = (int) (sss - (hh * 60 * 60)) / 60;
			int ss = (int) (sss - (hh * 60 * 60) - (mm * 60));
			result = hh + ":" + mm + ":" + ss;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String SubtractDate(String date1, String date2) {
		String result = "";
		try {
			Date start = DateTimeInstance().parse(date1);
			Date end = DateTimeInstance().parse(date2);
			long sss = (end.getTime() - start.getTime()) / 1000L;
			int dd = (int) sss / 86400;
			int hh = (int) (sss - (dd * 60 * 60 * 24)) / 3600;
			int mm = (int) (sss - (dd * 60 * 60 * 24) - (hh * 60 * 60)) / 60;
			int ss = (int) (sss - (dd * 60 * 60 * 24) - (hh * 60 * 60) - (mm * 60));
			result = dd + "-" + hh + ":" + mm + ":" + ss;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static int subDay(Date startTime, Date endTime) {
		int days = 0;
		Calendar can1 = Calendar.getInstance();
		can1.setTime(startTime);
		Calendar can2 = Calendar.getInstance();
		can2.setTime(endTime);
		int year1 = can1.get(1);
		int year2 = can2.get(1);

		Calendar can = null;
		if (can1.before(can2)) {
			days -= can1.get(6);
			days += can2.get(6);
			can = can1;
		} else {
			days -= can2.get(6);
			days += can1.get(6);
			can = can2;
		}
		for (int i = 0; i < Math.abs(year2 - year1); ++i) {
			days += can.getActualMaximum(6);
			can.add(1, 1);
		}

		return days;
	}

	public static int subDay(String startTime, String endTime) {
		int days = 0;
		try {
			Date date1 = DateInstance().parse(
					DateInstance().format(DateTimeInstance().parse(startTime)));
			Date date2 = DateInstance().parse(
					DateInstance().format(DateTimeInstance().parse(endTime)));
			Calendar can1 = Calendar.getInstance();
			can1.setTime(date1);
			Calendar can2 = Calendar.getInstance();
			can2.setTime(date2);
			int year1 = can1.get(1);
			int year2 = can2.get(1);

			Calendar can = null;
			if (can1.before(can2)) {
				days -= can1.get(6);
				days += can2.get(6);
				can = can1;
			} else {
				days -= can2.get(6);
				days += can1.get(6);
				can = can2;
			}
			for (int i = 0; i < Math.abs(year2 - year1); ++i) {
				days += can.getActualMaximum(6);
				can.add(1, 1);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return days;
	}

	public static long subtimeBurst(String startDate, String endDate,
			String timeBurst) throws ParseException {
		Date start = DateTimeInstance().parse(startDate);
		Date end = DateTimeInstance().parse(endDate);
		return subtimeBurst(start, end, timeBurst);
	}

	public static long subtimeBurst(Date startDate, Date endDate,
			String timeBurst) throws ParseException {
		long second = 0L;
		Pattern p = Pattern.compile("^\\d{2}:\\d{2}-\\d{2}:\\d{2}");
		Matcher m = p.matcher(timeBurst);
		if (m.matches()) {
			String[] a = timeBurst.split("-");
			int day = subDay(startDate, endDate);
			if (day > 0) {
				long firstMintues = 0L;
				long lastMintues = 0L;
				long daySecond = 0L;
				String strDayStart = DateInstance().format(startDate) + " "
						+ a[0] + ":00";
				String strDayEnd = DateInstance().format(startDate) + " "
						+ a[1] + ":00";
				Date dayStart = DateTimeInstance().parse(strDayStart);
				Date dayEnd = DateTimeInstance().parse(strDayEnd);
				daySecond = Subtract(dayStart, dayEnd);
				if ((((startDate.after(dayStart)) || (startDate
						.equals(dayStart)))) && (startDate.before(dayEnd)))
					firstMintues = (dayEnd.getTime() - startDate.getTime()) / 1000L;
				else if (startDate.before(dayStart)) {
					firstMintues = (dayEnd.getTime() - dayStart.getTime()) / 1000L;
				}
				dayStart = DateTimeInstance().parse(
						DateInstance().format(endDate) + " " + a[0] + ":00");
				dayEnd = DateTimeInstance().parse(
						DateInstance().format(endDate) + " " + a[1] + ":00");
				if ((endDate.after(dayStart))
						&& (((endDate.before(dayEnd)) || (endDate
								.equals(dayEnd)))))
					lastMintues = (endDate.getTime() - dayStart.getTime()) / 1000L;
				else if (endDate.after(dayEnd)) {
					lastMintues = (dayEnd.getTime() - dayStart.getTime()) / 1000L;
				}
				second = firstMintues + lastMintues;
				second += (day - 1) * daySecond;
			} else {
				String strDayStart = DateInstance().format(startDate) + " "
						+ a[0] + ":00";
				String strDayEnd = DateInstance().format(startDate) + " "
						+ a[1] + ":00";
				Date dayStart = DateTimeInstance().parse(strDayStart);
				Date dayEnd = DateTimeInstance().parse(strDayEnd);
				if ((((startDate.after(dayStart)) || (startDate
						.equals(dayStart))))
						&& (startDate.before(dayEnd))
						&& (endDate.after(dayStart))
						&& (((endDate.before(dayEnd)) || (endDate
								.equals(dayEnd))))) {
					second = (endDate.getTime() - startDate.getTime()) / 1000L;
				} else {
					if (startDate.before(dayStart)) {
						if (endDate.before(dayEnd))
							second = (endDate.getTime() - dayStart.getTime()) / 1000L;
						else {
							second = (dayEnd.getTime() - dayStart.getTime()) / 1000L;
						}
					}
					if (startDate.after(dayStart)) {
						if (endDate.before(dayEnd))
							second = (endDate.getTime() - startDate.getTime()) / 1000L;
						else {
							second = (dayEnd.getTime() - startDate.getTime()) / 1000L;
						}
					}
				}
				if (((startDate.before(dayStart)) && (endDate.before(dayStart)))
						|| ((startDate.after(dayEnd)) && (endDate.after(dayEnd))))
					second = 0L;
			}
		} else {
			second = (endDate.getTime() - startDate.getTime()) / 1000L;
		}
		return second;
	}

	public static Date calculate(String date, int second, String timeBurst) {
		Date start = null;
		try {
			start = DateTimeInstance().parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return calculate(start, second, timeBurst);
	}

	public static Date calculate(Date date, int second, String timeBurst) {
		Pattern p = Pattern.compile("^\\d{2}:\\d{2}-\\d{2}:\\d{2}");
		Matcher m = p.matcher(timeBurst);
		Calendar cal = Calendar.getInstance();
		if (m.matches()) {
			String[] a = timeBurst.split("-");
			try {
				Date dayStart = DateTimeInstance().parse(
						DateInstance().format(date) + " " + a[0] + ":00");
				Date dayEnd = DateTimeInstance().parse(
						DateInstance().format(date) + " " + a[1] + ":00");
				if (second >= 0) {
					if ((((date.after(dayStart)) || (date.equals(dayStart))))
							&& (((date.before(dayEnd)) || (date.equals(dayEnd))))) {
						cal.setTime(date);
					}
					if (date.before(dayStart)) {
						cal.setTime(dayStart);
					}
					if (date.after(dayEnd)) {
						cal.setTime(day(dayStart, 1));
					}

				} else {
					if ((((date.after(dayStart)) || (date.equals(dayStart))))
							&& (((date.before(dayEnd)) || (date.equals(dayEnd))))) {
						cal.setTime(date);
					}
					if (date.before(dayStart)) {
						cal.setTime(day(dayEnd, -1));
					}
					if (date.after(dayEnd)) {
						cal.setTime(dayEnd);
					}
				}
				int DaySecond = (int) Subtract(dayStart, dayEnd);
				int day = second / DaySecond;
				int remainder = second % DaySecond;

				cal.add(6, day);
				cal.add(13, remainder);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else {
			cal.setTime(date);
		}
		return cal.getTime();
	}
}